import type { ComputedRef, Ref } from "vue";
import type { MenuTreeResult } from "@/api/types";
import { debounce } from "es-toolkit";
import { computed, ref, watch } from "vue";
import { $t } from "@/plugins/i18n";

interface UseMenuFilter {
    /** 搜索关键字 */
    searchQuery: Ref<string>;
    /** 过滤后的数据 */
    filteredData: ComputedRef<MenuTreeResult[]>;
}

/** 菜单树搜索过滤 */
export function useMenuFilter(tableData: Ref<MenuTreeResult[]>): UseMenuFilter {
    const searchQuery = ref("");
    const debouncedQuery = ref("");

    watch(
        searchQuery,
        debounce((val: string) => {
            debouncedQuery.value = normalize(val);
        }, 300),
    );

    const filteredData = computed(() => {
        const query = debouncedQuery.value;
        if (!query) return tableData.value;

        return filterTree(tableData.value, (row: MenuTreeResult) => {
            const titleKey = row.meta?.title ?? "";
            const localizedTitle = $t(titleKey) || "";
            const titleHit = normalize(localizedTitle).includes(query) || normalize(titleKey).includes(query);
            const pathHit = normalize(row.path).includes(query);
            return titleHit || pathHit;
        });
    });

    return {
        searchQuery,
        filteredData,
    };
}

function normalize(val: unknown): string {
    return String(val ?? "").toLowerCase().trim();
}

function filterTree<T extends Record<string, any>>(
    nodes: T[],
    predicate: (n: T) => boolean,
    childrenKey = "children",
): T[] {
    return nodes
        .map((node) => {
            const children = Array.isArray(node[childrenKey])
                ? filterTree(node[childrenKey], predicate, childrenKey)
                : [];
            const hit = predicate(node);
            if (hit || children.length) {
                return { ...node, [childrenKey]: children };
            }
            return null as any;
        })
        .filter(Boolean);
}
